package errv

import (
	"fmt"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
)

type Code int32

type ErrWrap struct {
	Code   Code   `json:"code"`
	Msg    string `json:"msg"`
	Detail string `json:"detail"`
}

// Error 实现error的方法
func (e *ErrWrap) Error() string {
	msg := fmt.Sprintf("code:%d,[msg:%s]", e.Code, e.Msg)
	if e.Detail != "" {
		msg = msg + fmt.Sprintf(",detail:%+v", e.Detail)
	}
	return msg
}

// WithDetail ...
func (e *ErrWrap) WithDetail(str string, opt ...interface{}) *ErrWrap {
	e.Detail = fmt.Sprintf(str, opt...)
	return e
}

// Wrap ...
func (e *ErrWrap) Wrap(err error) *ErrWrap {
	if err != nil {
		e.Detail = err.Error()
	}
	return e
}

func (c Code) Error(msg string) *ErrWrap {
	return &ErrWrap{
		Code: c,
		Msg:  msg,
	}
}

// New ...
func New(code int, msg string) *ErrWrap {
	return Code(code).Error(msg)
}

// NewSample ...
func NewSample(code int) *ErrWrap {
	return Code(code).Error("")
}

func (c Code) GetDetail(err error) string {
	err = errors.Cause(err)
	if err == nil {
		return ""
	}
	var e ErrWrap
	if errors.As(err, e) {
		return cast.ToString(e.Detail)
	}
	return "未找到详情"
}

func (c Code) GetCode(err error) Code {
	err = errors.Cause(err)
	if err == nil {
		return 0
	}
	var e ErrWrap
	if errors.As(err, e) {
		return e.Code
	}
	return 0
}

func (c Code) GetMsg(err error) string {
	err = errors.Cause(err)
	if err == nil {
		return ""
	}
	var e ErrWrap
	if errors.As(err, e) {
		return e.Msg
	}
	return "未找到message"
}
